/**
 * $Id: DealOverDateNeedRespMTThread.java,v 1.18 2006/11/06 07:01:55 martin Exp $
 *
 * Copyright 2006 Skyinfo, Inc. All Rights Reserved.
 */
package com.haoxi.gateway.runner.datadeal;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.haoxi.gateway.common.SQLConst;
import com.haoxi.gateway.common.SYSConst;
import com.haoxi.gateway.runner.RunnerMgr;
import com.haoxi.gateway.runner.smscommand.SubmitCmd;
import com.haoxi.gateway.util.db.DBConnectUtil;
import com.haoxi.gateway.util.db.DealOracleDBUtil;

/**
 * 处理MTRespMap数据进行超时处理。
 * 
 * Revision History
 * 
 * 2006-5-31,star.Zhao,created it
 */
public class DealOverDateNeedRespMTThread implements Runnable {
    private final static Log log = LogFactory
            .getLog(DealOverDateNeedRespMTThread.class);

    private String name;
    /**
     * 定时检测时间
     */
    private int delay;
    
    private Map mtRespMap;
    /**
     * 运行
     */
    private boolean running = false;

    public DealOverDateNeedRespMTThread(Map mtRespMap, int delay) {
        this.delay = delay;
        this.mtRespMap = mtRespMap;
        this.name = "DealOverDateNeedRespMTThread";
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    public void run() {
        running = true;
        while (running) {
            /**
             * 需要的数据库名
             */
            Map systemConf = RunnerMgr.getInstance().getSystemConf();
            String gateway_history = (String) systemConf
                    .get(SYSConst.CONF_DB_HISTORY);
            String gateway_DBName = (String) systemConf
                    .get(SYSConst.CONF_DB_MYSQL);

            long currentTime = System.currentTimeMillis();
            // 删除过时的MTRESPMap中的数据
            List overDateSequenceIds = new ArrayList();
            List overDateSendedMTs = new ArrayList();

            synchronized (mtRespMap) {
                Iterator it = mtRespMap.keySet().iterator();
                while (it.hasNext()) {
                    String sequenceId = (String) it.next();
                    SubmitCmd submitCmd = (SubmitCmd) mtRespMap.get(sequenceId);
                    String submitTime = submitCmd.getSubmitTime();
                    // 判断是否已经超过30分钟,超过删除
                    long submitTimeLong = currentTime;
                    try {
                        submitTimeLong = SQLConst.dateformat.parse(submitTime)
                                .getTime();
                    } catch (ParseException e) {
                        log.error("dateformat.parse(submitTime) failure！");
                        submitTimeLong = currentTime;
                    }
                    
                    if (0 != submitTimeLong
                            && (currentTime - submitTimeLong) > SYSConst.OVERDATE_NEEDMTRESP_DATA_TIME) {
                        log.warn("-----------overdate Sequence: "+ submitCmd.getSequence() +"--------------");
                        log.warn("-----------overdate SubmitTime: "+ submitCmd.getSubmitTime() +"--------------");
                        log.warn("-----------overdate submitTimeLong: "+ SQLConst.dateformat.format(new Date(submitTimeLong))+"--------------");
                        log.warn("-----------overdate submitTimeLong: "+ submitTimeLong +"--------------");
                        log.warn("-----------overdate currentTime: "+ SQLConst.dateformat.format(new Date(currentTime))+"--------------");
                        log.warn("-----------overdate currentTime: "+ currentTime +"--------------");
                        overDateSequenceIds.add(sequenceId);
                        submitCmd.setSubmitStatus(DealOverDateDataMgr.OVERDATE_ERROR_INFO);
                        overDateSendedMTs.add(submitCmd);
                    }
                }
                // 删Map中的数据
                Iterator itr = overDateSequenceIds.iterator();
                while (itr.hasNext()) {
                    String sequenceId = (String) itr.next();
                    mtRespMap.remove(sequenceId);
                }
            }

            // 对超时数据进行saveMsgHistory存储
            if (overDateSendedMTs.size() > 0) {
                int[] res = DealOracleDBUtil.saveBatchMsgHistory(this.name,
                        overDateSendedMTs, gateway_history);
                if (null != res && res.length == overDateSendedMTs.size()) {
                    // 删除Map同步表中的数据
                    if (!this.deleteOverDateMTDealed(overDateSequenceIds,
                            gateway_DBName)) {
                        log
                                .error(" delete MTRespMap persistent Data failure ! overDateSequenceIds ：["
                                        + overDateSequenceIds + "]");
                    }

                } else {
                    log
                            .error(" saveMsgHistory for overDate MTResp persistent Data failure ! overDateSequenceIds ：["
                                    + overDateSequenceIds + "]");
                }
            }
            // 进入睡眠
            try {
                Thread.sleep(delay);
            } catch (InterruptedException ite) {
                log
                        .error(
                                "InterruptedException in DealOverDateDataThread.run()!",
                                ite);
            }
        }
    }

    /**
     * delete dealed overDate need mtResp MTData
     * 
     * @param ids
     */
    private boolean deleteOverDateMTDealed(List sequenceIDs, String dbName) {
        boolean result = false;
        if (sequenceIDs == null || sequenceIDs.size() <= 0) {
            return false;
        }
        int num = sequenceIDs.size();
        Connection conn = null;
        PreparedStatement psForSendedMT = null;
        try {
            conn = DBConnectUtil.open(dbName);
            psForSendedMT = conn
                    .prepareStatement(SQLConst.DELETE_NEED_SUBMITSTATUS_MTDATA);

            for (int i = 0; i < num; i++) {
                psForSendedMT.setString(1, (String) sequenceIDs.get(i));
                psForSendedMT.addBatch();
            }
            int[] res = psForSendedMT.executeBatch();

            if (res.length == num) {
                result = true;
                log
                        .debug("delete needMTResp MTData OK! the number of dealing result are: "
                                + num);
            } else {
                result = false;
                log.error("delete needMTResp MTData failure !!!!!!");
            }

        } catch (SQLException e) {
            log.error("SQLException:", e);
        } catch (Exception e) {
            log.error("other Exception:", e);
        } finally {
            try {
                if (psForSendedMT != null) {
                    psForSendedMT.clearBatch();
                    psForSendedMT.close();
                }

                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                log.error("close:", e);
            }
        }
        return result;
    }
}
